package com.CmJava.servlet.handlerAdapter;

import com.CmJava.servlet.DispatcherServlet;
import com.CmJava.servlet.executionChain.handlerMethodMapping.HandlerMethod;
import com.CmJava.servlet.modelAndView.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServletInvocableHandlerMethod {
    private HandlerMethod handlerMethod;

    private HandlerMethodReturnValueHandlerComposite returnValueHandlers = new HandlerMethodReturnValueHandlerComposite();

    public ServletInvocableHandlerMethod(HandlerMethod handlerMethod) {
        this.handlerMethod = handlerMethod;
    }

    public void invokeAndHandle(HttpServletRequest request, HttpServletResponse response, ModelAndViewContainer mavContainer, Object... objects) {
        Object returnValue = this.invokeForRequest(request,response, mavContainer, objects);
        if (returnValue == null) {
            throw new RuntimeException("method erro");
        }
        //将返回的结果封装在视图容器中
        this.returnValueHandlers.handleReturnValue(returnValue,  mavContainer, request,response);
    }


    private Object invokeForRequest(HttpServletRequest request, HttpServletResponse response, ModelAndViewContainer mavContainer, Object... providedArgs) {
        Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);
        return this.doInvoke(request,args);
    }

    private Object doInvoke(HttpServletRequest request, Object[] args) {
        HandlerMethod handlerMethod = DispatcherServlet.abstractHandlerMethodMapping.getMappingRegistry().getMappings().get(request.getRequestURI());
        return handlerMethod.invoke(args);
    }

    /**
     * 传参,因为绑定参数要获取方法的参数名，需要用到反编译技术，所以这里先不写
     * @param request
     * @param mavContainer
     * @param providedArgs
     * @return
     */
    private Object[] getMethodArgumentValues(HttpServletRequest request, ModelAndViewContainer mavContainer, Object[] providedArgs) {
        return providedArgs;
    }
}
